package com.dingreading.cloud.subject.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.AccountUtil;
import com.dingreading.cloud.common.util.IpUtil;
import com.dingreading.cloud.common.util.aliyun.CdnUtil;
import com.dingreading.cloud.subject.dto.CourseDto;
import com.dingreading.cloud.subject.dto.CourseListDto;
import com.dingreading.cloud.subject.entity.Course;
import com.dingreading.cloud.subject.entity.CourseDataLog;
import com.dingreading.cloud.subject.entity.CourseTypes;
import com.dingreading.cloud.subject.entity.CourseVideo;
import com.dingreading.cloud.subject.service.*;
import com.dingreading.cloud.subject.util.CdnUrlUtil;
import com.dingreading.cloud.subject.util.CourseTreeJsonUtil;
import com.dingreading.cloud.subject.util.CourseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RefreshScope
@RestController
@RequestMapping(value = "/front/course")
@Api(tags = "门店-学院资料管理")
public class FrontCourseController {

    /**
     * cdn加速域名
     */
    @Value("${aliYun.cdn.courseDomain}")
    private String cdnCourseDomain;

    @Resource
    protected CourseService courseService;
    @Resource
    protected CourseTypesService courseTypesService;
    @Resource
    protected CourseVideoService courseVideoService;
    @Resource
    protected CourseDataLogService courseDataLogService;
    @Resource
    private StoresService storesService;
    @Resource
    private CdnUrlUtil cdnUrlUtil;


    @ApiOperation(value = "获取主资料分类列表")
    @PostMapping(value = "/getMainCourseType", produces = "application/json; charset=UTF-8")
    public R<Object> getMainCourseType(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName
    ) {
        // 获取门店的学科
        List<Long> subjectIdList = storesService.getSubjectIdList(storeUid);
        if (CollectionUtils.isEmpty(subjectIdList))
            return R.fail("门店未分配科目，请联系运营人员");

        List<CourseTypes> list = courseTypesService.getMainCourseTypesV3(subjectIdList);
        return R.ok(list);
    }

    @ApiOperation(value = "获取主资料分类列表V2")
    @PostMapping(value = "/getMainCourseTypeV2", produces = "application/json; charset=UTF-8")
    public R<Object> getMainCourseTypeV2(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName
    ) {
        // 获取门店的学科
        List<Long> courseIdList = storesService.getCourseIdList(storeUid);
        if (CollectionUtils.isEmpty(courseIdList))
            return R.fail("门店未分配目录，请联系运营人员");

        List<CourseTypes> list = courseTypesService.getMainCourseTypesById(courseIdList);
        return R.ok(list);
    }

    @ApiOperation(value = "获取下级资料分类列表")
    @PostMapping(value = "/getChildCourseTypes", produces = "application/json; charset=UTF-8")
    public R<Object> getChildCourseTypes(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "主分类id") @RequestParam(value = "mainId") Long mainId
    ) {
        // 获取门店的学科
        List<Long> subjectIdList = storesService.getSubjectIdList(storeUid);
        if (CollectionUtils.isEmpty(subjectIdList))
            return R.fail("门店未分配科目，请联系运营人员");

        JSONArray treeJson = new JSONArray();
        List<CourseTypes> list = courseTypesService.getChildCourseTypesV3(mainId, subjectIdList);
        if (CollectionUtils.isNotEmpty(list)) {
            treeJson = CourseTreeJsonUtil.createChildCourseTypesTreeJson(list);
        }

        return R.ok(treeJson);
    }

    @ApiOperation(value = "获取分类下的资料")
    @PostMapping(value = "/getCourseList", produces = "application/json; charset=UTF-8")
    public R<Object> getCourseList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分类id") @RequestParam(value = "typeId") Long typeId,
            @ApiParam(value = "资料名") @RequestParam(value = "keyword", required = false) String keyword
    ) {
        if (typeId == null || typeId <= 0)
            return R.fail("未传递分类id");

        CourseTypes courseTypes = courseTypesService.getById(typeId);
        if (courseTypes == null) return R.fail("分类获取失败");
        if (courseTypes.getEnabled() != 1) return R.fail("分类已被禁用");
        if (!courseTypes.getLevelEnd().equals(1)) return R.fail("分类不是最后一层");

        List<CourseListDto> list = courseService.listByTypeIdAndKeyword(typeId, keyword);
        return R.ok(list);
    }

    @ApiOperation(value = "学院搜索功能")
    @PostMapping(value = "/search", produces = "application/json; charset=UTF-8")
    public R<Object> search(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "资料名") @RequestParam(value = "keyword") String keyword
    ) {
        List<CourseListDto> list = courseService.listByTypeIdAndKeyword(null, keyword);
        return R.ok(list);
    }

    @ApiOperation(value = "获取资料和视频")
    @PostMapping(value = "/getCourse", produces = "application/json; charset=UTF-8")
    public R<Object> getCourse(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "资料id") @RequestParam(value = "courseId") Long courseId
    ) {
        Course course = courseService.getById(courseId);
        if (course == null) {
            return R.fail("获取资料失败");
        }
        if (course.getFreeStatus() == null || !course.getFreeStatus().equals(1)) {
            // 非免费并且是体验账号，则没有有权限
            if (AccountUtil.isTyUser(corpUid)) {
                return R.fail("没有访问权限");
            }
        }

        List<CourseVideo> courseVideos = courseVideoService.getByCourseId(courseId, 1);
        CourseDto data = new CourseDto();
        data.setCourse(course);
        data.setCourseVideos(courseVideos);
        return R.ok(data);
    }

    @ApiOperation(value = "获取视频的观看地址")
    @PostMapping(value = "/getVideoUrl", produces = "application/json; charset=UTF-8")
    public R<Object> getVideoUrl(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "视频id") @RequestParam(value = "id") Long id
    ) {
        String referer = request.getHeader("referer");
        if (StringUtils.isBlank(referer)) {
            return R.fail("未获取到访问来源");
        }
        if (!referer.contains(CdnUtil.PROD_REFERER) && !referer.contains(CdnUtil.TEST_REFERER)) {
            return R.fail("请求跨域了");
        }
        String ip = IpUtil.getIpAddr(request);
        if (StringUtils.isBlank(ip)) {
            return R.fail("未获取到客户端ip");
        }

        CourseVideo courseVideo = courseVideoService.getById(id);
        if (courseVideo == null)
            return R.fail("获取视频失败");
        Course course = courseService.getById(courseVideo.getCourseId());
        if (course == null)
            return R.fail("获取资料失败");
        if (course.getFreeStatus() == null || !course.getFreeStatus().equals(1)) {
            // 非体验学科并且是体验账号，则没有有权限
            if (AccountUtil.isTyUser(corpUid)) {
                return R.fail("没有访问权限");
            }
        }

        String videoUrl = courseVideo.getUrl();
        if (StringUtils.isBlank(videoUrl))
            return R.fail("视频资源不存在");

        String authUrl = "";
        if (
                course.getMainTypeId().equals(174L) || course.getMainTypeId().equals(264L) ||
                        course.getMainTypeId().equals(269L) || course.getMainTypeId().equals(273L) ||
                        course.getMainTypeId().equals(277L) || course.getMainTypeId().equals(281L)
        ) {
            // 阿里云cdn的url鉴权，源站是备课服务器
            String urlAuthA = CdnUtil.getUrlAuthA("/" + videoUrl);
            authUrl = cdnCourseDomain + videoUrl + urlAuthA;
        } else {
            // 阿里云cdn的url鉴权，源站是阿里云OSS
            R<String> r = cdnUrlUtil.getCdnUrl(request, videoUrl);
            if (R.isError(r))
                return R.fail(r.getMsg());
            authUrl = r.getData();
        }

        // 更新观看次数
        courseVideoService.updateLookNum(id);

        // 保存观看记录
        CourseDataLog log = CourseUtil.newDataLog(1, corpUid, storeUid, storeName, staffUid, staffName,
                course.getId(), course.getName(), courseVideo.getId(), courseVideo.getName());
        courseDataLogService.saveOrUpdate(log);

        return R.ok(authUrl);
    }

    @ApiOperation(value = "获取下载资料的地址")
    @PostMapping(value = "/getDownloadUrl", produces = "application/json; charset=UTF-8")
    public R<Object> getDownloadUrl(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "下载资料id") @RequestParam(value = "id") Long id
    ) {
        String referer = request.getHeader("referer");
        if (StringUtils.isBlank(referer)) {
            return R.fail("未获取到访问来源");
        }
        if (!referer.contains(CdnUtil.PROD_REFERER) && !referer.contains(CdnUtil.TEST_REFERER)) {
            return R.fail("请求跨域了");
        }
        String ip = IpUtil.getIpAddr(request);
        if (StringUtils.isBlank(ip)) {
            return R.fail("未获取到客户端ip");
        }

        Course data = courseService.getById(id);
        if (data == null)
            return R.fail("获取失败");

        String dataUrl = data.getUrl();
        if (StringUtils.isBlank(dataUrl))
            return R.fail("没有下载地址");

        // 防暴击下载
        R<Object> duplicateDownload = courseDataLogService.preventDuplicateDownload(storeUid, staffUid, data.getId());
        if (R.isError(duplicateDownload))
            return duplicateDownload;

        // 文件类型
        String fileType = StringUtils.substringAfterLast(dataUrl, ".");

        // 阿里云cdn的url鉴权，源站是阿里云OSS
        R<String> r = cdnUrlUtil.getCdnUrl(request, dataUrl);
        if (R.isError(r))
            return R.fail(r.getMsg());
        String authUrl = r.getData();

        // 更新下载次数
        courseService.updateDownloadNum(id);

        // 保存观看记录
        CourseDataLog log = CourseUtil.newDataLog(2, corpUid, storeUid, storeName, staffUid, staffName,
                data.getId(), data.getName(), null, null);
        courseDataLogService.saveOrUpdate(log);

        JSONObject object = new JSONObject();
        object.put("fileType", fileType);
        object.put("url", authUrl);
        return R.ok(object);
    }

    @ApiOperation(value = "获取资料和视频-测试")
    @GetMapping(value = "/get", produces = "application/json; charset=UTF-8")
    public R<Object> get(
            @ApiParam(value = "资料id") @RequestParam(value = "id") Long id
    ) {
        Course course = courseService.getById(id);

        List<CourseVideo> courseVideos = courseVideoService.getByCourseId(id, 1);
        CourseDto data = new CourseDto();
        data.setCourse(course);
        data.setCourseVideos(courseVideos);
        return R.ok(data);
    }

}
